package com.educate.ucenter.shiro.seesion;

import com.educate.common.utils.cache.RedisManager;
import com.educate.common.web.JsonUtils;
import com.educate.common.web.WebUtils;
import com.educate.ucenter.shiro.filter.ParamLegalFilter;
import lombok.extern.log4j.Log4j2;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.mgt.eis.CachingSessionDAO;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.Serializable;


/**
 *
 */
@Log4j2
@Component
public class UserSessionDao extends CachingSessionDAO {

    public static final String CENTER_USER_SESSION_ID = "center_user_session_id";

//    private ConcurrentMap<Serializable, UserSession> sessions = new ConcurrentHashMap<>();

    @Resource RedisManager redisManager;

    @Override
    protected Serializable generateSessionId(Session session) {
        return ParamLegalFilter.uid;
    }

    @Override
    protected Serializable doCreate(Session session) {
        Serializable sessionId = this.generateSessionId(session);
        this.assignSessionId(session, sessionId);
        this.storeSession(sessionId, session);
        return sessionId;
    }

    protected void storeSession(Serializable id, Session session) {
        if (id == null) {
            throw new NullPointerException("id argument cannot be null.");
        } else {
            WebUtils.getRequest().setAttribute(getClass().getName() + id, session);
        }
    }

    @Override
    protected Session doReadSession(Serializable sessionId) {
        UserSession session = (UserSession) WebUtils.getRequest().getAttribute(getClass().getName() + sessionId);
        if (session == null) {
            session = getSession(sessionId);
            if (session != null) {
                WebUtils.getRequest().setAttribute(getClass().getName() + sessionId, session);
            }
        }
        return session;
    }

    @Override
    protected void doUpdate(Session session) {
        this.storeSession(session.getId(), session);
    }

    @Override
    protected void doDelete(Session session) {
        if (session == null) {
            throw new NullPointerException("session argument cannot be null.");
        } else {
            Serializable sessionId = session.getId();
            if (sessionId != null) {
                WebUtils.getRequest().setAttribute(getClass().getName() + sessionId, null);
                removeSession(sessionId);
            }
        }
    }

//    public Collection<Session> getActiveSessions() {
//        Collection<UserSession> values = this.sessions.values();
//        return CollectionUtils.isEmpty(values) ? Collections.emptySet() : Collections.unmodifiableCollection(values);
//    }

    public void logined(Serializable sessionId) {
        UserSession userSession = (UserSession) WebUtils.getRequest().getAttribute(getClass().getName() + sessionId);
//        this.sessions.putIfAbsent(sessionId, userSession);
        redisManager.set(CENTER_USER_SESSION_ID + sessionId, JsonUtils.writeValueAsString(userSession));
    }

    public UserSession getSession(Serializable uid) {
        return redisManager.get(CENTER_USER_SESSION_ID + uid, UserSession.class);
    }

    public void removeSession(Serializable uid) {
        redisManager.remove(CENTER_USER_SESSION_ID + uid);
    }
}
